package com.petdog.module.tools.service.impl;

import com.petdog.module.tools.dto.LostPetDTO;
import com.petdog.module.tools.dto.LostPetRequest;
import com.petdog.module.tools.dto.NearbyLostPetsRequest;
import com.petdog.module.tools.service.GeoHashUtils;
import com.petdog.module.tools.service.LostPetService;
import com.petdog.module.tools.service.PetRecognitionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 寻宠启事服务实现类
 */
@Service
public class LostPetServiceImpl implements LostPetService {

    @Autowired
    private PetRecognitionService petRecognitionService;

    @Autowired
    private GeoHashUtils geoHashUtils;

    // 模拟数据库存储
    private final Map<Long, LostPetDTO> lostPetStorage = new HashMap<>();
    private Long nextId = 1L;

    /**
     * 发布寻宠启事
     */
    @Override
    public Long publishLostPet(LostPetRequest request, MultipartFile petPhoto, Long userId) {
        // 验证文件
        if (petPhoto == null || petPhoto.isEmpty()) {
            throw new RuntimeException("请上传宠物照片");
        }

        // 检测图像中是否包含宠物
        if (!petRecognitionService.detectPetInImage(petPhoto)) {
            throw new RuntimeException("未识别到宠物，请上传更清晰的图片");
        }

        // 上传宠物照片
        String photoUrl = petRecognitionService.uploadPetPhoto(petPhoto);

        // 创建寻宠启事物体
        LostPetDTO lostPetDTO = new LostPetDTO();
        BeanUtils.copyProperties(request, lostPetDTO);
        lostPetDTO.setId(nextId++);
        lostPetDTO.setUserId(userId);
        lostPetDTO.setPetPhotoUrl(photoUrl);
        lostPetDTO.setCreateTime(LocalDateTime.now());
        lostPetDTO.setStatus(0); // 0-进行中
        lostPetDTO.setMaskedContactPhone(maskPhoneNumber(request.getContactPhone()));

        // 存储寻宠启事
        lostPetStorage.put(lostPetDTO.getId(), lostPetDTO);

        // 模拟向附近用户推送消息
        // 实际项目中应该调用消息推送服务
        System.out.println("向附近用户推送寻宠消息：" + lostPetDTO.getPetName());

        return lostPetDTO.getId();
    }

    /**
     * 获取附近的寻宠启事
     */
    @Override
    public List<LostPetDTO> getNearbyLostPets(NearbyLostPetsRequest request) {
        Double currentLat = request.getLatitude();
        Double currentLon = request.getLongitude();
        Integer radius = request.getRadius();

        // 计算并过滤附近的寻宠启事
        List<LostPetDTO> nearbyPets = lostPetStorage.values().stream()
                .filter(pet -> pet.getStatus() == 0) // 只查询进行中的寻宠启事
                .map(pet -> {
                    // 计算距离
                    double distance = geoHashUtils.calculateDistance(
                            currentLat, currentLon,
                            pet.getLatitude(), pet.getLongitude());
                    pet.setDistance(distance);
                    return pet;
                })
                .filter(pet -> pet.getDistance() <= radius) // 过滤半径范围内的
                .sorted(Comparator.comparing(LostPetDTO::getDistance)) // 按距离排序
                .collect(Collectors.toList());

        // 分页处理
        int page = request.getPage() - 1;
        int pageSize = request.getPageSize();
        int start = page * pageSize;
        int end = Math.min(start + pageSize, nearbyPets.size());

        if (start >= nearbyPets.size()) {
            return Collections.emptyList();
        }

        return nearbyPets.subList(start, end);
    }

    /**
     * 上传所见宠物照片并进行匹配
     */
    @Override
    public Map<String, Object> uploadSighting(MultipartFile petPhoto, Double longitude, Double latitude, Long userId) {
        // 验证文件
        if (petPhoto == null || petPhoto.isEmpty()) {
            throw new RuntimeException("请上传宠物照片");
        }

        // 检测图像中是否包含宠物
        if (!petRecognitionService.detectPetInImage(petPhoto)) {
            throw new RuntimeException("未识别到宠物，请上传更清晰的图片");
        }

        // 查找附近的寻宠启事
        NearbyLostPetsRequest nearbyRequest = new NearbyLostPetsRequest();
        nearbyRequest.setLatitude(latitude);
        nearbyRequest.setLongitude(longitude);
        nearbyRequest.setRadius(5); // 5公里范围内
        nearbyRequest.setPage(1);
        nearbyRequest.setPageSize(50);

        List<LostPetDTO> nearbyLostPets = getNearbyLostPets(nearbyRequest);

        // 模拟匹配过程
        // 在实际项目中，应该调用真实的图像匹配算法
        Map<String, Object> result = new HashMap<>();
        if (nearbyLostPets.isEmpty()) {
            result.put("matched", false);
            result.put("message", "未找到匹配的寻宠启事，感谢您的参与");
            return result;
        }

        // 模拟找到匹配的宠物（实际项目中需要进行真正的图像匹配）
        LostPetDTO matchedPet = nearbyLostPets.get(0);
        double matchScore = 85 + Math.random() * 15; // 85%-100%的匹配度

        if (matchScore >= 80) { // 匹配度≥80%判定为成功
            result.put("matched", true);
            result.put("matchScore", matchScore);
            result.put("petName", matchedPet.getPetName());
            result.put("message", "已找到匹配的寻宠启事，已通知宠物主人");

            // 模拟通知寻宠主人
            System.out.println("通知寻宠主人：有用户上传疑似您丢失的宠物照片，匹配度 " + 
                    String.format("%.1f", matchScore) + "%");
        } else {
            result.put("matched", false);
            result.put("message", "未找到匹配的寻宠启事，感谢您的参与");
        }

        return result;
    }

    /**
     * 标记寻宠启事为已找回
     */
    @Override
    public void markAsFound(Long lostPetId, Long userId) {
        LostPetDTO lostPet = lostPetStorage.get(lostPetId);
        if (lostPet == null) {
            throw new RuntimeException("寻宠启事不存在");
        }

        // 验证用户是否为发布者
        if (!Objects.equals(lostPet.getUserId(), userId)) {
            throw new RuntimeException("无权操作，仅发布者可标记为已找回");
        }

        lostPet.setStatus(1); // 1-已找回
        lostPetStorage.put(lostPetId, lostPet);
    }

    /**
     * 获取用户发布的寻宠启事
     */
    @Override
    public List<LostPetDTO> getUserLostPets(Long userId) {
        return lostPetStorage.values().stream()
                .filter(pet -> Objects.equals(pet.getUserId(), userId))
                .sorted(Comparator.comparing(LostPetDTO::getCreateTime).reversed())
                .collect(Collectors.toList());
    }

    /**
     * 手机号脱敏处理
     */
    private String maskPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.length() != 11) {
            return phoneNumber;
        }
        return phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7);
    }
}